package com.ccteam.admin.view.fragments.album

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import cn.hutool.core.date.DateUtil
import com.bumptech.glide.Glide
import com.ccteam.admin.R
import com.ccteam.admin.REFRESH_REQUEST_KEY
import com.ccteam.admin.core.ADD_TYPE
import com.ccteam.admin.core.EDIT_TYPE
import com.ccteam.admin.databinding.FragmentAlbumEditBinding
import com.ccteam.admin.utils.EventObserver
import com.ccteam.admin.utils.LoadMessage
import com.ccteam.admin.view.bean.SelectInfoResult
import com.ccteam.admin.view.bean.UploadResult
import com.ccteam.admin.view.fragments.common.SelectFragment.Companion.SELECT_ARTIST
import com.ccteam.admin.view.fragments.common.SelectFragment.Companion.SELECT_REQUEST_KEY
import com.ccteam.admin.view.fragments.common.SelectFragment.Companion.SELECT_RESULT
import com.ccteam.admin.view.fragments.common.UploadFragment
import com.ccteam.admin.viewmodels.album.AlbumEditViewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import java.text.SimpleDateFormat
import java.time.LocalTime
import java.time.format.DateTimeFormatter

@AndroidEntryPoint
class AlbumEditFragment : Fragment() {

    private var _binding: FragmentAlbumEditBinding? = null
    private val binding get() = _binding!!

    private val albumEditViewModel by viewModels<AlbumEditViewModel>()
    private val args: AlbumEditFragmentArgs by navArgs()

    /**
     * 选择图片的内容
     * 选择完手机中的图片后，将其存储到ViewModel中并进行对应UI更新
     */
    private val selectImage = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
        uri?.let {
            albumEditViewModel.setAlbumUrl(it.toString())
            albumEditViewModel.updateAlbumEditInfo()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setFragmentResultListener(SELECT_REQUEST_KEY){ _, bundle ->
            val albumArtistInfo = bundle.getParcelable<SelectInfoResult>(SELECT_RESULT)

            albumArtistInfo?.let {
                albumEditViewModel.setAlbumArtist(it.selectId,it.selectTitle)
                albumEditViewModel.setAlbumArtistSuccess(true)
            }
        }

        setFragmentResultListener(UploadFragment.UPLOAD_REQUEST_KEY) { _, bundle ->
            bundle.getParcelable<UploadResult>(UploadFragment.UPLOAD_URL_RESULT)?.let { result ->
                albumEditViewModel.setAlbumUrl(result.url)
                albumEditViewModel.setAlbumUrlSuccess(true)
                albumEditViewModel.updateAlbumEditInfo()
            }
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentAlbumEditBinding.inflate(inflater,container,false)
        binding.btnDelete.isVisible = args.albumEditType == EDIT_TYPE
        if(args.albumEditType == EDIT_TYPE){
            binding.btnEdit.setIconResource(R.drawable.ic_edit)
            binding.btnEdit.text = getString(R.string.description_confirm_edit)
        } else {
            binding.btnEdit.setIconResource(R.drawable.ic_add)
            binding.btnEdit.text = getString(R.string.description_album_edit_add)
        }
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        binding.containerAlbumArtistSelect.setOnClickListener {
            findNavController().navigate(AlbumEditFragmentDirections
                .actionAlbumEditFragmentToSelectFragment(SELECT_ARTIST))
        }

        binding.btnUpload.setOnClickListener {
            selectImage.launch("image/*")
        }

        binding.btnEdit.setOnClickListener {
            albumEditViewModel.editOrAddAlbumInfo()
        }

        binding.statusView.setRetryClickListener {
            albumEditViewModel.refreshAlbumInfo()
        }

        binding.btnDelete.setOnClickListener {
            // 删除该专辑
            MaterialAlertDialogBuilder(requireContext())
                .setTitle(R.string.description_dialog_delete)

                .setMessage(getString(R.string.description_dialog_delete_album_message,albumEditViewModel.editAlbumInfo.value?.albumName))
                .setNegativeButton(R.string.description_cancel) { _,_ -> }
                .setPositiveButton(R.string.description_delete) { _,_ ->
                    albumEditViewModel.deleteAlbumInfo()
                }.show()
        }

        albumEditViewModel.editButtonEnable.observe(viewLifecycleOwner, {
            binding.btnEdit.isEnabled = it
        })

        albumEditViewModel.deleteButtonEnable.observe(viewLifecycleOwner, {
            binding.btnDelete.isEnabled = it
        })

        albumEditViewModel.editAlbumInfo.observe(viewLifecycleOwner, {
            if(it != null){
                notifyEditContentChanged(it)
            }
        })

        albumEditViewModel.loadMessage.observe(viewLifecycleOwner, {
            binding.containerEdit.isVisible = it is LoadMessage.NotLoading
            binding.statusView.changeToLoadingStatus(it is LoadMessage.Loading)
            binding.statusView.changeToErrorStatus(it)
        })

        binding.editAlbumName.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                albumEditViewModel.setAlbumName(text.toString())
                val nameSuccess = if(text.toString().isEmpty() && text.toString().length !in 1..100){
                    inputLayout.error = getString(R.string.description_album_edit_error_albumName)
                    false
                } else {
                    inputLayout.error = null
                    true
                }
                albumEditViewModel.setAlbumNameSuccess(nameSuccess)
            }
        }

        binding.editAlbumIntroduction.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                albumEditViewModel.setAlbumIntroduction(text.toString())
            }
        }

        binding.editAlbumYear.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                albumEditViewModel.setAlbumYear(text.toString())

                val yearSuccess = try {
                    val date = DateUtil.format(DateUtil.parse(text),"yyyy-MM-dd")
                    if(date.isNullOrEmpty()){
                        throw NullPointerException()
                    }
                    albumEditViewModel.setAlbumYear(date)
                    inputLayout.error = null
                    true
                } catch (e: Exception){
                    inputLayout.error = getString(R.string.description_album_edit_error_albumYear)
                    false
                }
                albumEditViewModel.setAlbumYearSuccess(yearSuccess)
            }
        }

        binding.editImgUrl.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                albumEditViewModel.setAlbumUrl(text.toString())
                val imgSuccess = if(text.toString().isEmpty()){
                    inputLayout.error = getString(R.string.description_album_edit_error_img)
                    false
                } else {
                    inputLayout.error = null
                    true
                }
                albumEditViewModel.setAlbumUrlSuccess(imgSuccess)
            }
        }

        albumEditViewModel.editLoadMessage.observe(viewLifecycleOwner,EventObserver{
            binding.btnEdit.setLoading(it is LoadMessage.Loading)
            if(it is LoadMessage.Error){
                Snackbar.make(
                    binding.root,
                    it.errorMessage.description.toString(),
                    Snackbar.LENGTH_SHORT
                ).setAnchorView(binding.btnEdit).show()
            } else if(it is LoadMessage.Success){
                Snackbar.make(
                    binding.root,
                    getString(R.string.description_success),
                    Snackbar.LENGTH_SHORT
                ).setAnchorView(binding.btnEdit).show()
                setFragmentResult(REFRESH_REQUEST_KEY, bundleOf(REFRESH_REQUEST_KEY to true))
                findNavController().navigateUp()
            }
        })

        albumEditViewModel.deleteLoadMessage.observe(viewLifecycleOwner,EventObserver{
            binding.btnDelete.setLoading(it is LoadMessage.Loading)
            if(it is LoadMessage.Error){
                Snackbar.make(
                    binding.root,
                    it.errorMessage.description.toString(),
                    Snackbar.LENGTH_SHORT
                ).setAnchorView(binding.btnEdit).show()
            } else if(it is LoadMessage.Success){
                Snackbar.make(
                    binding.root,
                    getString(R.string.description_success),
                    Snackbar.LENGTH_SHORT
                ).setAnchorView(binding.btnEdit).show()
                setFragmentResult(REFRESH_REQUEST_KEY, bundleOf(REFRESH_REQUEST_KEY to true))
                findNavController().navigateUp()
            }
        })
    }

    private fun notifyEditContentChanged(albumInfo: AlbumEditViewModel.AlbumEditInfo) = with(binding){
        editAlbumId.editText?.setText(albumInfo.id)
        editAlbumName.editText?.setText(albumInfo.albumName)
        editAlbumIntroduction.editText?.setText(albumInfo.introduction)
        editAlbumYear.editText?.setText(albumInfo.albumYear)
        tvSelectArtist.text = getString(R.string.description_album_edit_artist_info,albumInfo.artistName ?: "无")
        editImgUrl.editText?.setText(albumInfo.imgUrl)
        notifyImgContentChanged(albumInfo.imgUrl)
    }

    private fun notifyImgContentChanged(imgUrl: String?){
        Glide.with(binding.imageAlbumPhoto)
            .load(imgUrl)
            .placeholder(R.drawable.img_default_album_big)
            .into(binding.imageAlbumPhoto)
    }

    override fun onDestroyView() {
        super.onDestroyView()

        binding.editAlbumName.clearOnEditTextAttachedListeners()
        binding.editAlbumIntroduction.clearOnEditTextAttachedListeners()
        binding.editAlbumYear.clearOnEditTextAttachedListeners()
        binding.editImgUrl.clearOnEditTextAttachedListeners()

        _binding = null
    }
}